The routine arena_getmem(n)
returns a pointer to (at least)
n
bytes of memory. Note that n
is rounded up to ensure
that returned pointers are always aligned. We align to the nearest
8 byte segment, since that'll satisfy the more common 2-byte and
4-byte alignment restrictions too.
@o arena.c @void *arena_getmem(n) size_t n; char *q; char *p = arena->avail; n = (n + 7) & 7; /* ensuring alignment to 8 bytes */ q = p + n; if (q <= arena->limit) arena->avail = q; return p; @<Find a new chunk of memory@> @| arena_getmem @
If the current chunk doesn't have adequate space (at least n
bytes) we examine the rest of the list of chunks (starting at
arena->next
) looking for a chunk with adequate space. If n
is very large, we may not find it right away or we may not find a
suitable chunk at all.
@d Find a new chunk...
@
Chunk *ap = arena;
Chunk *np = ap->next;
while (np)
char *v = sizeof(Chunk) + (char *) np;
if (v + n <= np->limit)
np->avail = v + n;
arena = np;
return v;
ap = np;
np = ap->next;
@<Allocate a new chunk of memory@>
@
If there isn't a suitable chunk of memory on the free list, then we need to allocate a new one. @d Allocate a new ch... @ size_t m = n + 10000; np = (Chunk *) malloc(m); np->limit = m + (char *) np; np->avail = n + sizeof(Chunk) + (char *) np; np->next = NULL; ap->next = np; arena = np; return sizeof(Chunk) + (char *) np; @